package org.zerofwk.example.datastruct.linklist;

/**
 * desc:
 * 单向链表示例
 *
 * @author: Administrator
 * @date: 2021/4/1 10:47
 */
public class SlinkedListTest {
    public static void main(String[] args) {
        SlinkedList<Person> list = new SlinkedList<Person>();
        Person p1 = new Person(21, "nick1", "testp1@qq.com");
        Person p2 = new Person(22, "nick2", "testp2@qq.com");
        Person p3 = new Person(23, "nick3", "testp3@qq.com");
        Person p4 = new Person(24, "nick4", "testp4@qq.com");
        Person p5 = new Person(25, "nick5", "testp6@qq.com");
        list.addToTail(p1);
        list.addToTail(p2);
        list.addToTail(p3);
        list.addToTail(p4);
        list.addToTail(p5);
        System.out.println("原始链表，链表元素个数："+list.getLinkedSize());
        list.show();

//        Person p222 = new Person(222, "nick222", "testp222@qq.com");
//        list.addNode(p222, 2);
//        System.out.println("链表插入一个数据：");
//        list.show();
//
//        Person p333 = new Person(333, "nick333", "testp333@qq.com");
//        list.modifyNode(p333, 5);
//        System.out.println("链表修改一个数据：");
//        list.show();
        list.del(p1);
        list.del(p2);
        list.del(p3);
        list.del(p4);
        list.del(p5);
        System.out.println("删除链表后，链表元素个数："+list.getLinkedSize());
        list.show();

    }


    static class SlinkedList<T> {

        private int linkedSize;
        private SlinkNode<T> headNode;

        public SlinkedList() {
            linkedSize = 0;
            headNode = null;
        }

        public void addToTail(T data) {
            SlinkNode newNode = new SlinkNode(data);
            if (headNode == null) {
                headNode = newNode;
                linkedSize++;
            } else {
                SlinkNode tempNode = headNode;
                while (tempNode.nextNode != null) {
                    tempNode = tempNode.nextNode;
                }
                tempNode.nextNode = newNode;
                linkedSize++;
            }
        }

        /**
         * 指定下标后边插入数据
         *
         * @param data 新数据
         * @param idx  指定下标
         */
        public void addNode(T data, int idx) {
            SlinkNode newNode = new SlinkNode(data);
            if (idx >= linkedSize) {
                addToTail(data);
                return;
            }

            if (idx < linkedSize) {
                int tempIdx = 0;
                SlinkNode tempNode = headNode;
                while (tempNode.nextNode != null) {
                    tempNode = tempNode.nextNode;
                    tempIdx++;
                    if (tempIdx == idx) {
                        break;
                    }
                }
                newNode.nextNode = tempNode.nextNode;
                tempNode.nextNode = newNode;
                linkedSize++;
            }
        }

        /**
         * 修改指定下标数据的值
         *
         * @param data 新值
         * @param idx  指定下标
         */
        public void modifyNode(T data, int idx) {
            if (idx >= linkedSize) {
                System.out.printf("没有找到要修改的数据，数据下标：%d \n", idx);
                return;
            }

            int tempIdx = 0;
            SlinkNode tempNode = headNode;
            while (tempNode != null) {
                //比较当前数据是否是指定下标的
                if (tempIdx == idx) {
                    break;
                }
                tempNode = tempNode.nextNode;
                tempIdx++;
            }
            //修改数据
            tempNode.data = data;
        }

        /**
         * @param data
         */
        public void del(T data) {
            SlinkNode tempNode = headNode;
            while (tempNode != null) {
                T fData = (T)tempNode.data;
                if(fData.equals(data)){
                    headNode = headNode.nextNode;
                    linkedSize--;
                    break;
                }else {
                    SlinkNode ttNode = tempNode.nextNode;
                    if (ttNode != null) {
                        T dd = (T) ttNode.data;
                        //移除 data
                        if (dd.equals(data)) {
                            tempNode.nextNode = ttNode.nextNode;
                            linkedSize--;
                            break;
                        }
                    }
                }

                tempNode = tempNode.nextNode;
            }
        }

        public void show() {
            SlinkNode tempNode = headNode;
            while (tempNode != null) {
                System.out.println(tempNode.data);
                tempNode = tempNode.nextNode;
            }
        }

        public int getLinkedSize() {
            return linkedSize;
        }

        private class SlinkNode<T> {
            private T data;
            private SlinkNode nextNode;

            public SlinkNode(T tmpData) {
                data = tmpData;
                nextNode = null;
            }
        }
    }
}


